import { HubConnectionBuilder, LogLevel } from '@microsoft/signalr'
import { useGameStore } from '../stores/game'

class SignalRService {
  constructor() {
    this.connection = null
    this.reconnectAttempts = 0
    this.maxReconnectAttempts = 5
    this.reconnectDelay = 1000
    this.roomCode = null
    this.playerId = null
  }

  // 获取游戏状态存储（延迟初始化）
  get gameStore() {
    try {
      return useGameStore()
    } catch (error) {
      console.warn('Pinia store not available yet:', error)
      return null
    }
  }

  // 连接到服务器
  async connect(roomCode, playerId) {
    // 确保先断开现有连接
    if (this.connection) {
      try {
        await this.disconnect()
      } catch (error) {
        console.error('Error disconnecting before reconnect:', error)
      }
    }
    
    this.roomCode = roomCode
    this.playerId = playerId

    if (this.gameStore) {
      this.gameStore.setConnectionStatus('connecting')
    }

    try {
      // 创建SignalR连接
      const apiBaseUrl = import.meta.env.VITE_API_BASE_URL || 'http://localhost:5000'
      const hubUrl = `${apiBaseUrl}/gamehub`
      console.log('Connecting to SignalR hub:', hubUrl)

      this.connection = new HubConnectionBuilder()
        .withUrl(hubUrl, {
          skipNegotiation: false,
          transport: 1 // WebSockets
        })
        .withAutomaticReconnect([0, 2000, 10000, 30000]) // 重连策略
        .configureLogging(LogLevel.Debug)
        .build()

      this.setupEventListeners()

      console.log('Starting SignalR connection...')
      await this.connection.start()
      console.log('SignalR connection started successfully')

      if (this.gameStore) {
        this.gameStore.setConnectionStatus('connected')
      }
      this.reconnectAttempts = 0

    } catch (error) {
      console.error('SignalR connection failed:', error)
      if (this.gameStore) {
        this.gameStore.setConnectionStatus('disconnected')
        this.gameStore.setErrorMessage('连接服务器失败')
      }
      // 确保连接对象被清除
      this.connection = null
    }
  }

  // 断开连接
  async disconnect() {
    if (this.connection) {
      try {
        // 移除所有事件监听器
        this.connection.off('PlayerJoined')
        this.connection.off('PlayerLeft')
        this.connection.off('GameStarted')
        this.connection.off('GameEnded')
        this.connection.off('PaintActionReceived')
        this.connection.off('AreaUpdated')
        this.connection.off('TimerUpdate')
        this.connection.off('RoomStateUpdate')
        this.connection.off('Error')
        
        await this.connection.stop()
      } catch (error) {
        console.error('Error disconnecting:', error)
      } finally {
        this.connection = null
      }
    }
    if (this.gameStore) {
      this.gameStore.setConnectionStatus('disconnected')
    }
  }

  // 设置事件监听器
  setupEventListeners() {
    if (!this.connection) return

    // 连接状态变化
    this.connection.onreconnecting((error) => {
      console.log('SignalR reconnecting:', error)
      if (this.gameStore) {
        this.gameStore.setConnectionStatus('connecting')
      }
    })

    this.connection.onreconnected((connectionId) => {
      console.log('SignalR reconnected:', connectionId)
      if (this.gameStore) {
        this.gameStore.setConnectionStatus('connected')
      }
    })

    // 连接关闭
    this.connection.onclose(async (error) => {
      console.log('SignalR connection closed:', error)
      if (this.gameStore) {
        this.gameStore.setConnectionStatus('disconnected')
      }

      // 自动重连
      if (this.reconnectAttempts < this.maxReconnectAttempts) {
        setTimeout(async () => {
          this.reconnectAttempts++
          try {
            // 重新创建连接
            if (!this.connection) {
              await this.connect(this.roomCode, this.playerId)
            } else {
              await this.connection.start()
            }
          } catch (err) {
            console.error('Reconnection failed:', err)
          }
        }, this.reconnectDelay * this.reconnectAttempts)
      }
    })

    // 游戏事件监听
    this.connection.on('PlayerJoined', this.handlePlayerJoined.bind(this))
    this.connection.on('PlayerLeft', this.handlePlayerLeft.bind(this))
    this.connection.on('GameStarted', this.handleGameStarted.bind(this))
    this.connection.on('GameEnded', this.handleGameEnded.bind(this))
    this.connection.on('PaintActionReceived', this.handlePaintActionReceived.bind(this))
    this.connection.on('AreaUpdated', this.handleAreaUpdated.bind(this))
    this.connection.on('TimerUpdate', this.handleTimerUpdate.bind(this))
    this.connection.on('RoomStateUpdate', this.handleRoomStateUpdate.bind(this))
    this.connection.on('Error', this.handleError.bind(this))
  }

  // 断开连接
  async disconnect() {
    if (this.connection) {
      try {
        await this.connection.stop()
      } catch (error) {
        console.error('Error disconnecting:', error)
      }
      this.connection = null
    }
    if (this.gameStore) {
      this.gameStore.setConnectionStatus('disconnected')
    }
  }

  // 加入房间
  async joinRoom(roomCode, playerInfo) {
    if (!this.connection) return

    try {
      await this.connection.invoke('JoinRoom', {
        roomCode,
        playerId: playerInfo.id,
        nickname: playerInfo.nickname
      })
    } catch (error) {
      console.error('Failed to join room:', error)
    }
  }

  // 离开房间
  async leaveRoom() {
    if (!this.connection) return

    try {
      await this.connection.invoke('LeaveRoom')
      await this.disconnect()
    } catch (error) {
      console.error('Failed to leave room:', error)
    }
  }

  // 开始游戏
  async startGame() {
    if (!this.connection) return

    try {
      await this.connection.invoke('StartGame')
    } catch (error) {
      console.error('Failed to start game:', error)
    }
  }

  // 发送涂色动作
  async sendPaintAction(paintData) {
    if (!this.connection) return

    try {
      await this.connection.invoke('PaintAction', {
        ...paintData,
        timestamp: Date.now()
      })
    } catch (error) {
      console.error('Failed to send paint action:', error)
    }
  }

  // 重新开始游戏
  async restartGame() {
    if (!this.connection) return

    try {
      await this.connection.invoke('RestartGame')
    } catch (error) {
      console.error('Failed to restart game:', error)
    }
  }

  // 强制终止游戏
  async forceEndGame() {
    if (!this.connection) return

    try {
      await this.connection.invoke('ForceEndGame')
    } catch (error) {
      console.error('Failed to force end game:', error)
    }
  }

  // 事件处理器
  handlePlayerJoined(playerInfo) {
    console.log('Player joined:', playerInfo)
    if (this.gameStore) {
      this.gameStore.addPlayer(playerInfo)
      // 更新Canvas的玩家颜色映射
      this.updateCanvasPlayerColors()
    }
  }

  handlePlayerLeft(playerId) {
    console.log('Player left:', playerId)
    if (this.gameStore) {
      this.gameStore.removePlayer(playerId)
      // 更新Canvas的玩家颜色映射
      this.updateCanvasPlayerColors()
    }
  }

  handleGameStarted(gameInfo) {
    console.log('Game started:', gameInfo)
    if (this.gameStore) {
      this.gameStore.setGameStatus('playing')
      this.gameStore.setGameDuration(gameInfo.duration)
      this.gameStore.setRemainingTime(gameInfo.duration)
      this.gameStore.setPlayers(gameInfo.players)
    }
  }

  handleGameEnded(gameResult) {
    console.log('Game ended:', gameResult)
    if (this.gameStore) {
      this.gameStore.setGameStatus('finished')
      this.gameStore.setPlayers(gameResult.players)
    }
  }

  handlePaintActionReceived(paintData) {
    console.log('Paint action received:', paintData)
    // 这里会触发Canvas组件的远程绘制
    window.dispatchEvent(new CustomEvent('remotePaintAction', {
      detail: paintData
    }))
  }

  handleAreaUpdated(areaData) {
    console.log('Area updated:', areaData)
    // 更新玩家面积
    if (this.gameStore) {
      areaData.areas.forEach(({ playerId, area }) => {
        this.gameStore.updatePlayerArea(playerId, area)
      })
    }
  }

  handleTimerUpdate(timeLeft) {
    console.log('Timer update:', timeLeft)
    if (this.gameStore) {
      this.gameStore.setRemainingTime(timeLeft)
    }
  }

  handleRoomStateUpdate(roomState) {
    console.log('Room state update:', roomState)
    console.log('Game duration from server:', roomState.gameDuration)
    if (this.gameStore) {
      this.gameStore.setCurrentRoom(roomState.room)
      this.gameStore.setPlayers(roomState.players)
      this.gameStore.setGameStatus(roomState.status)
      if (roomState.remainingTime !== undefined) {
        this.gameStore.setRemainingTime(roomState.remainingTime)
      }
      if (roomState.gameDuration !== undefined) {
        console.log('Setting game duration to:', roomState.gameDuration)
        this.gameStore.setGameDuration(roomState.gameDuration)
      }
    }
  }

  // 更新Canvas的玩家颜色映射
  updateCanvasPlayerColors() {
    if (this.gameStore && this.gameStore.players) {
      const playerColors = {}
      this.gameStore.players.forEach(player => {
        playerColors[player.id] = player.color
      })
      
      // 通知Canvas组件更新玩家颜色映射
      window.dispatchEvent(new CustomEvent('updatePlayerColors', {
        detail: playerColors
      }))
    }
  }

  handleError(error) {
    console.error('SignalR error:', error)
    console.error('Error type:', typeof error)
    console.error('Error keys:', error ? Object.keys(error) : 'null/undefined')
    console.error('Error message:', error?.message)
    console.error('Error details:', JSON.stringify(error, null, 2))

    let errorMessage = '发生未知错误'

    if (error) {
      if (typeof error === 'string') {
        errorMessage = error
      } else if (error.message) {
        errorMessage = error.message
      } else if (error.error) {
        errorMessage = error.error
      } else if (error.Message) {
        errorMessage = error.Message
      }
    }

    // 添加特定错误处理
    if (errorMessage.includes('加入房间失败')) {
      errorMessage += ' (可能原因：房间不存在、房间已满、密码错误或网络问题)'
      
      // 如果是密码错误，提示用户重新输入
      if (error.details && error.details.includes('Password')) {
        errorMessage += ' [请检查房间密码]'
      }
    }

    if (this.gameStore) {
      this.gameStore.setErrorMessage(errorMessage)
      
      // 对于加入房间失败的情况，自动重试
      if (errorMessage.includes('加入房间失败') && 
          this.reconnectAttempts < this.maxReconnectAttempts &&
          !(error.details && error.details.includes('Password'))) {
        setTimeout(() => {
          console.log('尝试自动重连...')
          this.connect(this.roomCode, this.playerId)
        }, 2000)
      }
    }
  }

  // 获取连接状态
  isConnected() {
    return this.connection && this.connection.state === 'Connected'
  }

  // 获取连接实例
  getConnection() {
    return this.connection
  }
}

// 创建单例实例
const signalRService = new SignalRService()

export default signalRService
